#ifndef __CSPHERE_H__
#define __CSPHERE_H__

#include "StdDefs.h"
#include "CMathFixed.h"
#include "CVector3d.h"
#include "CSpace.h"
#include "CPlane.h"


class CSphere
{
public:
	CSphere(){}
	CSphere( fixed i, fixed j, fixed k, fixed rad );
	CSphere( const CVector3d& translation, fixed rad );
	CSphere( const CSphere& s );
	~CSphere(){}

	static boolean		Sweep( const CVector3d& pos1, fixed r1, const CVector3d& pos2, fixed r2,
							   const CVector3d& v1, const CVector3d& v2, fixed &t, CVector3d& pt );

	static boolean		Sweep( const CVector3d& pos, fixed r, const CPlane& plane,
							   const CVector3d& v, fixed &t, CVector3d& pt );
	
	static boolean		Intersects( const CVector3d& pos1, fixed r1, const CVector3d& pos2, fixed r2 ); // sphere - sphere
	static boolean		Intersects( const CVector3d& pos1, fixed r1, const CVector3d& segA, const CVector3d& segB ); // sphere - segment
	static boolean		Intersects( const CVector3d& pos, fixed r, const CPlane& p, CSpace::Relativity& relativity );

	CSphere&			Set( fixed i, fixed j, fixed k, fixed rad );
	CSphere&			Set( const CVector3d& translation, fixed rad );
	CSphere&			Set( fixed const* v );

	//Space				DetermineSpace( fixed signedDistanceToPoint ) const;

	boolean				Sweep( const CSphere& sphere, const CVector3d& v1, const CVector3d& v2, fixed& t, CVector3d& pt ) const;
	boolean				Sweep( const CPlane& plane, const CVector3d& v, fixed &t, CVector3d& pt ) const;

	boolean				Intersects( const CSphere& sphere ) const;
	boolean				Intersects( const CVector3d& sega, const CVector3d& segb ) const;
	boolean				Intersects( const CPlane& p, CSpace::Relativity& relativity ) const;

	//+jmb: add sweep test - etc

	fixed				m_radius;
	CVector3d			m_translation;
};




inline 
CSphere::CSphere( fixed i, fixed j, fixed k, fixed rad )
{ 
	m_radius = rad;
	m_translation.Set( i, j, k ); 
}


inline
CSphere::CSphere( const CVector3d& translation, fixed rad )
{
	m_radius = rad; 
	m_translation = translation;
}


inline 
CSphere::CSphere( const CSphere& s )
{
	m_radius = s.m_radius; 
	m_translation = s.m_translation;
}


inline 
CSphere& CSphere::Set( fixed i, fixed j, fixed k, fixed rad )
{ 
	m_radius = rad;
	m_translation.Set( i, j, k );

	return *this;
}

inline
CSphere& CSphere::Set( fixed const* v ) 
{
	m_radius = v[3];
	m_translation.Set( v[0], v[1], v[2] );

	return *this;
}

inline
CSphere& CSphere::Set( const CVector3d& translation, fixed rad )
{
	m_radius = rad; 
	m_translation = translation;

	return *this;
}


inline	
boolean CSphere::Sweep( const CSphere& sphere, const CVector3d& v1, const CVector3d& v2, fixed& t, CVector3d& pt ) const
{
	return Sweep( m_translation, m_radius, sphere.m_translation, sphere.m_radius, v1, v2, t, pt );
}


inline
boolean	CSphere::Sweep( const CPlane& plane, const CVector3d& v, fixed &t, CVector3d& pt ) const
{
	return Sweep( m_translation, m_radius, plane, v, t, pt );
}


inline
boolean CSphere::Intersects( const CSphere& sphere ) const
{
	return Intersects( m_translation, m_radius, sphere.m_translation, sphere.m_radius );
}


inline
boolean CSphere::Intersects( const CVector3d& sega, const CVector3d& segb ) const
{
	return Intersects( m_translation, m_radius, sega, segb );
}


inline
boolean	CSphere::Intersects( const CPlane& p, CSpace::Relativity& relativity ) const
{
	return Intersects( m_translation, m_radius, p, relativity );
}




#endif // __CSPHERE_H__